# Script by Danke!
from pyspades.server import grenade_packet, block_action, weapon_reload, create_player, set_tool, set_color, input_data, weapon_input
from pyspades.world import Grenade
from pyspades.common import Vertex3, coordinates, to_coordinates
from pyspades.collision import distance_3d_vector
from pyspades.constants import *
from twisted.internet.reactor import callLater
from commands import name, get_player, add, admin
import math
import random
from pyspades.contained import KillAction
from pyspades.common import make_color
from pyspades.server import set_tool

ARMOR, EXTENMAG, TEAMMATE, TELEP, REGEN, POISON, NADEPL =  xrange(7)
INTEL_PUNISHMENT = True

@admin
def powerdev(connection, power, level, value = None):
    if value is None:
        player = connection
    else:
        player = get_player(connection.protocol, value)
    power = int(power)
    level = int(level)
    if power > -1 and power < 7 and level > -1 and level < 4:
        player.intel_p_lvl[power] = level
        return player.explain_power()
    if level == 4 and power > -1 and power < 7 :
        player.irpg_four = power
        return player.explain_power()
    if level == 5 and power > -1 and power < 7 :
        player.irpg_five = power
        return player.explain_power()
add(powerdev)

@admin
def forcecap(connection):
    if connection.protocol.blue_team.flag.player is not None:
        connection.protocol.blue_team.flag.player.capture_flag()
    if connection.protocol.green_team.flag.player is not None:
        connection.protocol.green_team.flag.player.capture_flag()
add(forcecap)

def d(connection):
    connection.blockdetonate()
add(d)

def clearpowers(connection):
    connection.intel_clear()
    return "You've sucessfully lost all your powers!"
add(clearpowers)

def five(connection, value = 7):
    if connection.four_points is None:
        connection.four_points = [0,0,0,0,0,0,0]
    value = int(value)
    if value > 6 or value < 0:
        connection.send_chat("You must have all badges to upgrade to level 5.")
        connection.send_chat("You can only lose or change the power with /clearpower")
        connection.send_chat("You can not have any other powers")        
        connection.send_chat("You can have only one level 5 power at a time")        
        connection.send_chat("You can change between /four and /five freely")        
    elif sum(connection.four_points) >= 280 or connection.irpg_five < 7:
        connection.intel_power_pref = value
        connection.intel_clear()
        connection.irpg_five = value
        if value == 0:
            connection.send_chat("You do more damage the less life you have.")
            connection.send_chat("Berserk level 5:")
        elif value == 1:
            connection.send_chat("You are periodically told the position of the enemy intel carrier while sneaking.")
            connection.send_chat("Intel Radar level 5:")
        elif value == 2:
            connection.send_chat("Teammates can touch you for a refill (with cooldown)")
            connection.send_chat("Mobile Tent level 5:")
        elif value == 3:
            connection.send_chat("Holding sneak while shooting will switch positions with the target (twice per life)")
            connection.send_chat("Freaky Friday level 5:")
        elif value == 4:
            connection.send_chat("Like Paratrooper, but your landing is explosive to enemies")
            connection.send_chat("Shock Trooper level 5:")
        elif value == 5:
            connection.send_chat("One block you place poisons enemies who come near it (only 1 block at a time)")
            connection.send_chat("Poison Block level 5:")
        elif value == 6:
            connection.send_chat("Your bullets have a chance of turning the enemy into a timebomb")
            connection.send_chat("Sticky Bombs level 5:")
        connection.kill()
    else:
        connection.send_chat("Type /badges for info on badges")
        connection.send_chat("You need to have all badges in order to upgrade")
add(five)


def four(connection, value = 7):
    value = int(value)
    if value > 6 or value < 0:
        connection.send_chat("You must have at least 10 levels to upgrade")
        connection.send_chat("You can only lose or change the power with /clearpowers or /four")
        connection.send_chat("You can not have any other powers")        
        connection.send_chat("You can have only one level 4 power at a time")        
        connection.send_chat("Type /four # to upgrade to a level 4 power (0-6)")        
    elif sum(connection.intel_p_lvl) >= 10 or connection.irpg_four < 7 or connection.irpg_five < 7:
        connection.intel_power_pref = value
        connection.intel_clear()
        connection.irpg_four = value
        if value == 0:
            connection.send_chat("You take 1/15 damage from weapons, but you have no gun.")
            connection.send_chat("Zombie level 4:")
        elif value == 1:
            connection.send_chat("Your weapon fires a burst of shots when fired manually.")
            connection.send_chat("Burst Fire level 4:")
        elif value == 2:
            connection.send_chat("While sneaking, teammates near you heal 5 hp/s")
            connection.send_chat("Team Medic level 4:")
        elif value == 3:
            connection.send_chat("You are invisible for 3 seconds after teleporting (nade teleporting only)")
            connection.send_chat("Ninja Warp level 4:")
        elif value == 4:
            connection.send_chat("Half of the time, you spawn in the sky where you died.")
            connection.send_chat("Paratrooper level 4:")
        elif value == 5:
            connection.send_chat("Your bullets have a chance of emptying an enemy's gun.")
            connection.send_chat("Disarm level 4:")
        elif value == 6:
            connection.send_chat("Blocks you place explode when broken. (5 per life) or type /d to detonate them!")
            connection.send_chat("Blocksplosion level 4:")                
        connection.kill()
    else:
        connection.send_chat("You need to have at least 10 levels in order to upgrade")
add(four)

def power(connection, value = 7):
    value = int(value)
    if connection.irpg_four > 6 and connection.irpg_five > 6:
        if value > 6:
            connection.send_chat("Type /current to see current powers")
            connection.send_chat("Type /powerpref for info on setting prefered power")
            connection.send_chat('2 - Good Teammate     5 - Poison Bullets     6 - Nadesplosion')
            connection.send_chat('1 - Extended Mag      4 - Regeneration')
            connection.send_chat('0 - Armor                 3 - Teleportation')
            connection.send_chat("Type /power # to read about a power:")
        elif value == ARMOR:
            connection.send_chat("Level 3 - Take 1/8 damage from body-shots and grenades.")
            connection.send_chat("Level 2 - Take 1/4 damage from body-shots and grenades.")
            connection.send_chat("Level 1 - Take 1/2 damage from body-shots and grenades.")
            connection.send_chat("The power of Armor:")
        elif value == EXTENMAG:
            connection.send_chat("Level 3 - You spawn with 30 extra bullets loaded.")
            connection.send_chat("Level 2 - You spawn with 20 extra bullets loaded.")
            connection.send_chat("Level 1 - You spawn with 10 extra bullets loaded.")
            connection.send_chat("The power of Extended Mag:")
        elif value == TEAMMATE:
            connection.send_chat("Good Teammate also cures poison when healing!")
            connection.send_chat("Level 3 - You and nearby teammates are healed 20 hp per kill + 10 per headshot.")
            connection.send_chat("Level 2 - You and nearby teammates are healed 20 hp per kill")
            connection.send_chat("Level 1 - You and nearby teammates are healed 10 hp per headshot.")
            connection.send_chat("The power of the Good Teammate:")
        elif value == TELEP:
            connection.send_chat("Level 3 - Nade teleport + break blocks with your weapon to teleport. (4 uses) ")
            connection.send_chat("Level 2 - Nade teleport + break blocks with your weapon to teleport. (2 uses)")
            connection.send_chat("Level 1 - Use grenades to teleport to where they explode.")
            connection.send_chat("The power of Teleportation:")
        elif value == REGEN:
            connection.send_chat("Regen does not work while poisoned!")
            connection.send_chat("Level 3 - Regenerate 5 HP per second.")
            connection.send_chat("Level 2 - Regenerate 3 HP per second.")
            connection.send_chat("Level 1 - Regenerate 2 HP per second.")
            connection.send_chat("The power of Regeneration:")
        elif value == POISON:
            connection.send_chat("Level 3 - Your bullets do 3hp/s poison damage")
            connection.send_chat("Level 2 - Your bullets do 2hp/s poison damage.")
            connection.send_chat("Level 1 - Your bullets do 1hp/s poison damage.")
            connection.send_chat("The power of Poison Bullets:")
        else:
            connection.send_chat("Level 3 - A 30% chance headshots cause an explosion.")
            connection.send_chat("Level 2 - A 15% chance headshots cause an explosion.")
            connection.send_chat("Level 1 - A 10% chance headshots cause an explosion.")
            connection.send_chat("The power of Nadesplosion:")
    elif connection.irpg_four < 7:
        if value > 6:
            connection.send_chat("Type /current to see current powers")
            connection.send_chat('2 - Team Medic        5 - Disarm     6 - Blocksplosion')
            connection.send_chat('1 - Burst Fire        4 - Paratrooper')
            connection.send_chat('0 - Zombie            3 - Ninja Warp')
            connection.send_chat("Type /power # to read about a power:")
        elif value == ARMOR:
            connection.send_chat("Level 4 - You take 1/15 damage from weapons, but you have no gun.")
            connection.send_chat("The power of Zombie:")
        elif value == EXTENMAG:
            connection.send_chat("Level 4 - Your weapon fires a burst of shots when fired manually.")
            connection.send_chat("The power of Burst Fire:")
        elif value == TEAMMATE:
            connection.send_chat("Level 4 - While sneaking, teammates near you heal 5 hp/s")
            connection.send_chat("The power of Team Medic:")
        elif value == TELEP:
            connection.send_chat("Level 4 - You are invisible for 3 seconds after teleporting (nade teleporting only)")
            connection.send_chat("The power of Ninja Warp:")
        elif value == REGEN:
            connection.send_chat("Level 4 - Half of the time, you spawn in the sky where you died.")
            connection.send_chat("The power of Paratrooper:")
        elif value == POISON:
            connection.send_chat("Level 4 - Your bullets have a chance of emptying an enemy's gun.")
            connection.send_chat("The power of Disarm:")
        else:
            connection.send_chat("Level 4 - Blocks you place explode when broken. (5 per life) or type /d to detonate them!")
            connection.send_chat("The power of Blocksplosion:")
    elif connection.irpg_five < 7:
        if value > 6:
            connection.send_chat("Type /current to see current powers")
            connection.send_chat('2 - Mobile Tent       5 - Poison Block     6 - Sticky Bombs')
            connection.send_chat('1 - Intel Radar       4 - Shock Trooper')
            connection.send_chat('0 - Berserk           3 - Freaky Friday')
            connection.send_chat("Type /power # to read about a power:")
        elif value == 0:
            connection.send_chat("You do more damage the less life you have.")
            connection.send_chat("Berserk level 5:")
        elif value == 1:
            connection.send_chat("You are periodically told the position of the enemy intel carrier while sneaking.")
            connection.send_chat("Intel Radar level 5:")
        elif value == 2:
            connection.send_chat("Teammates can touch you for a refill (with cooldown)")
            connection.send_chat("Mobile Tent level 5:")
        elif value == 3:
            connection.send_chat("Holding sneak while shooting will switch positions with the target (twice per life)")
            connection.send_chat("Freaky Friday level 5:")
        elif value == 4:
            connection.send_chat("Like Paratrooper, but your landing is explosive to enemies")
            connection.send_chat("Shock Trooper level 5:")
        elif value == 5:
            connection.send_chat("One block you place poisons enemies who come near it (only 1 block at a time)")
            connection.send_chat("Poison Block level 5:")
        elif value == 6:
            connection.send_chat("Your bullets have a chance of turning the enemy into a timebomb")
            connection.send_chat("Sticky Bombs level 5:")

add(power)

def powerpref(connection, value = 7):
    value = int(value)
    if value > 6:
        connection.send_chat('2 - Good Teammate     5 - Poison Bullets     6 - Nadesplosion')
        connection.send_chat('1 - Extended Mag      4 - Regeneration')
        connection.send_chat('0 - Armor             3 - Teleportation')
        connection.send_chat("Type /powerpref # to set a preference")
        connection.send_chat("Preference is ignored on your first intel grab.")
    elif value <= 6 and connection.irpg_four > 6:
        connection.intel_power_pref = value
        message = "Preference saved - "
        message += "Armor" if value == 0 else ""
        message += "Extended Mag" if value == 1 else ""
        message += "Good Teammate" if value == 2 else ""
        message += "Teleportation" if value == 3 else ""
        message += "Regeneration" if value == 4 else ""
        message += "Poison Bullets" if value == 5 else ""
        message += "Nadesplosion" if value == 6 else ""
        connection.send_chat('%s' % message)
    elif value <= 6 and connection.irpg_four < 6:
        connection.intel_power_pref = value
        message = "Preference saved - "
        message += "Zombie" if value == 0 else ""
        message += "Burst Fire" if value == 1 else ""
        message += "Mobile Tent" if value == 2 else ""
        message += "Ninja Warp" if value == 3 else ""
        message += "Paratrooper" if value == 4 else ""
        message += "Disarm" if value == 5 else ""
        message += "Blocksplosion" if value == 6 else ""
        connection.send_chat('%s' % message)
add(powerpref)

def current(connection, value = None):
    if value is None:
        connection.send_chat("Type /clearpowers to remove all your current powers")
        message = "You have " + connection.explain_power()
    else:
        player = get_player(connection.protocol, value)
        message = player.name + " has " + player.explain_power()
    return message

add(current)

def apply_script(protocol, connection, config):
    class IntelPowerConnection(connection):

        def irpg_drop_weapon(player):
            weapon = player.weapon_object
            weapon.set_shoot(False)
            weapon.current_ammo = 0
            weapon_reload.player_id = player.player_id
            weapon_reload.clip_ammo = 0
            weapon_reload.reserve_ammo = 0
            player.send_contained(weapon_reload)

        def irpg_reload_weapon(player, new_ammo):
            weapon = player.weapon_object
            weapon.set_shoot(False)
            weapon.current_ammo = new_ammo
            weapon_reload.player_id = player.player_id
            weapon_reload.clip_ammo = weapon.current_ammo
            weapon_reload.reserve_ammo = weapon.current_stock
            player.send_contained(weapon_reload)

        def on_login(self, name):
            self.intel_clear()
            self.ohmygodjcabomb = None
            self.omgjab = None
            self.poison_block = None
            self.mobile_cooldown = 0
            self.four_points = [0,0,0,0,0,0,0]
            self.headshot_splode = False
            self.other_second = False
            self.irpg_points = 4
            self.freaky_ammo = 2
            self.irpg_four = 7
            self.irpg_five = 7
            self.parachute_pos = None
            self.parachute_count = 1
            self.blocksplode_count = 5
            self.deadly = False
            connection.on_login(self, name)

        def explain_temp(self):
            message = ""
            message = ("Armor level %s" % self.intel_p_lvl[0]) if self.intel_temp == 0 else message
            message = ("Extended Mag level %s" % self.intel_p_lvl[1]) if self.intel_temp == 1 else message
            message = ("Good Teammate level %s" % self.intel_p_lvl[2]) if self.intel_temp == 2 else message
            message = ("Teleportation level %s" % self.intel_p_lvl[3]) if self.intel_temp == 3 else message
            message = ("Regeneration level %s" % self.intel_p_lvl[4]) if self.intel_temp == 4 else message
            message = ("Poison Bullets level %s" % self.intel_p_lvl[5]) if self.intel_temp == 5 else message
            message = ("Nadesplosion level %s" % self.intel_p_lvl[6]) if self.intel_temp == 6 else message
            return(message)

        def explain_power(self):
            message = "powers: "
            message += ("Armor level %s, " % self.intel_p_lvl[0]) if self.intel_p_lvl[0] > 0 else ""
            message += ("Extended Mag level %s, " % self.intel_p_lvl[1]) if self.intel_p_lvl[1] > 0 else ""
            message += ("Good Teammate level %s, " % self.intel_p_lvl[2]) if self.intel_p_lvl[2] > 0 else ""
            message += ("Teleportation level %s, " % self.intel_p_lvl[3]) if self.intel_p_lvl[3] > 0 else ""
            message += ("Regeneration level %s, " % self.intel_p_lvl[4]) if self.intel_p_lvl[4] > 0 else ""
            message += ("Poison Bullets level %s, " % self.intel_p_lvl[5]) if self.intel_p_lvl[5] > 0 else ""
            message += ("Nadesplosion level %s, " % self.intel_p_lvl[6]) if self.intel_p_lvl[6] > 0 else ""
            message += ("Zombie level 4, ") if self.irpg_four == 0 else ""
            message += ("Burst Fire level 4, ") if self.irpg_four == 1 else ""
            message += ("Team Medic level 4, ") if self.irpg_four == 2 else ""
            message += ("Ninja Warp level 4, ") if self.irpg_four == 3 else ""
            message += ("Paratrooper level 4, ") if self.irpg_four == 4 else ""
            message += ("Disarm level 4, ") if self.irpg_four == 5 else ""
            message += ("Blocksplosion level 4, ") if self.irpg_four == 6 else ""
            message += ("Berserk level 5, ") if self.irpg_five == 0 else ""
            message += ("Intel Radar level 5, ") if self.irpg_five == 1 else ""
            message += ("Mobile Tent level 5, ") if self.irpg_five == 2 else ""
            message += ("Freaky Friday level 5, ") if self.irpg_five == 3 else ""
            message += ("Shock Trooper level 5, ") if self.irpg_five == 4 else ""
            message += ("Poison Block level 5, ") if self.irpg_five == 5 else ""
            message += ("Sticky Bombs level 5, ") if self.irpg_five == 6 else ""
            if message == "powers: ":
                message = "no powers"
            else:
                message = message[:-2]
            return(message)

        def explain_badges(self):
            message = "Badges: "
            if self.four_points is None:
                self.four_points = [0,0,0,0,0,0,0]
            if self.four_points == [0,0,0,0,0,0,0]:
                return None
            message += ("Zombie Badge, ") if self.four_points[0] >= 5 else ""
            message += ("Burst Badge, ") if self.four_points[1] >= 5 else ""
            message += ("Medic Badge, ") if self.four_points[2] >= 250 else ""
            message += ("Ninja Badge, ") if self.four_points[3] >= 5 else ""
            message += ("Para Badge, ") if self.four_points[4] >= 5 else ""
            message += ("Disarm Badge, ") if self.four_points[5] >= 5 else ""
            message += ("Splode Badge, ") if self.four_points[6] >= 5 else ""
            if message == "Badges: ":
                return None
            message = message[:-2]
            return message

        def explain_four(self):
            message = ""
            message += ("You take 1/15 damage but you have no gun!") if self.irpg_four == 0 else "" # zombie
            message += ("Your weapon fires a burst of shots when fired manually") if self.irpg_four == 1 else "" # rapid
            message += ("Sneaking near teammates heals them 5hp/s") if self.irpg_four == 2 else "" # medic
            message += ("You are teleported where your grenades explode and turn invisible for 3 seconds") if self.irpg_four == 3 else "" #ninja
            message += ("Every other time you spawn, you spawn in the way up in air above where you died") if self.irpg_four == 4 else "" #paratroop
            message += ("Your bullets have a chance of emptying your opponents gun, forcing them to reload") if self.irpg_four == 5 else "" #disarm
            message += ("1st five blocks you place explode when broken. Type /d to detonate them all!") if self.irpg_four == 6 else "" #blocksplo
            message += ("You do more damage the less life you have.") if self.irpg_five == 0 else ""
            message += ("You are periodically told the position of the enemy intel carrier. while sneaking") if self.irpg_five == 1 else ""
            message += ("Teammates can touch you for a refill (with cooldown)") if self.irpg_five == 2 else ""
            message += ("Holding sneak while shooting will switch positions with the target (twice per life)") if self.irpg_five == 3 else ""
            message += ("Like Paratrooper, but your landing is explosive to enemies") if self.irpg_five == 4 else ""
            message += ("One block you place poisons enemies who come near it (only 1 block at a time)") if self.irpg_five == 5 else ""
            message += ("Your bullets have a chance of turning the enemy into a timebomb") if self.irpg_five == 6 else ""
            if message != "":
                self.send_chat("%s" % message)

        def nadesplode(self, hit_player):
            self.protocol.world.create_object(Grenade, 0.0, hit_player.world_object.position, None, Vertex3(), self.nadepl_exploded)
            grenade_packet.value = 0.1
            grenade_packet.player_id = self.player_id
            grenade_packet.position = (hit_player.world_object.position.x, hit_player.world_object.position.y, hit_player.world_object.position.z)
            grenade_packet.velocity = (0.0, 0.0, 0.0)
            self.protocol.send_contained(grenade_packet)

        def shocksplode(self):
            self.protocol.world.create_object(Grenade, 0.0, self.world_object.position, None, Vertex3(), self.shocksploded)
            grenade_packet.value = 0.1
            grenade_packet.player_id = self.player_id
            grenade_packet.position = (self.world_object.position.x, self.world_object.position.y, self.world_object.position.z)
            grenade_packet.velocity = (0.0, 0.0, 0.0)
            self.protocol.send_contained(grenade_packet)

        def blockdetonate(self):
            if self.protocol.blocksplode_info is None:
                self.protocol.blocksplode_info = {}
            templist = []
            temp_count = 0
            for block in self.protocol.blocksplode_info:
                player = self.protocol.blocksplode_info[block]
                if player == self and self.irpg_four == 6 and temp_count < 10:
                    temp_count += 1
                    x, y, z = block[0], block[1], block[2]
                    self.blocksplode(x, y, z)
                    templist.append(block)
            for block in templist:
                del self.protocol.blocksplode_info[block]

        def blocksplode(self, x, y, z):
            pos = (x, y, z)
            self.protocol.world.create_object(Grenade, 0.0, Vertex3(*pos), None, Vertex3(), self.nadepl_exploded)
            grenade_packet.value = 0.1
            grenade_packet.player_id = self.player_id
            grenade_packet.position = (x, y, z)
            grenade_packet.velocity = (0.0, 0.0, 0.0)
            self.protocol.send_contained(grenade_packet)

        def nadepl_exploded(self, grenade):
            self.headshot_splode = True
            connection.grenade_exploded(self, grenade)

        def shocksploded(self, grenade):
            if self.name is None or self.team.spectator:
                return
            if grenade.team is not None and grenade.team is not self.team:
                # could happen if the player changed team
                return
            position = grenade.position
            x = position.x
            y = position.y
            z = position.z
            if x < 0 or x > 512 or y < 0 or y > 512 or z < 0 or z > 63:
                return
            x = int(math.floor(x))
            y = int(math.floor(y))
            z = int(math.floor(z))
            for player in self.team.other.get_players():
                if not player.hp:
                    continue
                damage = grenade.get_damage(player.world_object.position)
                if damage == 0:
                    continue
                returned = self.on_hit(damage, player, GRENADE_KILL, grenade)
                if returned == False:
                    continue
                elif returned is not None:
                    damage = returned
                player.set_hp(player.hp - damage, self, 
                    hit_indicator = position.get(), type = GRENADE_KILL,
                    grenade = grenade)
            if self.on_block_destroy(x, y, z, GRENADE_DESTROY) == False:
                return
            map = self.protocol.map
            for nade_x in xrange(x - 1, x + 2):
                for nade_y in xrange(y - 1, y + 2):
                    for nade_z in xrange(z - 1, z + 2):
                        if map.destroy_point(nade_x, nade_y, nade_z):
                            self.on_block_removed(nade_x, nade_y, nade_z)
            block_action.x = x
            block_action.y = y
            block_action.z = z
            block_action.value = GRENADE_DESTROY
            block_action.player_id = self.player_id
            self.protocol.send_contained(block_action, save = True)
            self.protocol.update_entities()


        def on_hit(self, hit_amount, hit_player, type, grenade):
            value = connection.on_hit(self, hit_amount, hit_player, type, grenade)
            if value is not None or hit_player.team == self.team:
                return value
            value = hit_amount
            dice_roll = random.randint(1, 100)
            if self.irpg_five == 6 and dice_roll <= 5 and hit_player.ohmygodjcabomb is None:
                hit_player.ohmygodjcabomb = 5
                hit_player.omgjab = self
                hit_player.send_chat("Oh my god, %s , A BOMB!" % hit_player.name )
                self.send_chat("You hit %s with a sticky bomb!" % hit_player.name )
            if dice_roll <= (50 / self.weapon_object.ammo) and self.irpg_deadly: # 5% rifle, 1.6% smg, 8.3% shotgun
                return 100
                hit_player.send_chat("You have been instakilled by %s !" % self.name)
                self.send_chat("You instakilled %s !" % hit_player.name)
            if hit_player.intel_p_lvl[0] > 0:
                if type != HEADSHOT_KILL and type != MELEE_KILL:
                    if hit_player.intel_p_lvl[0] == 3:
                        value *= .125
                    if hit_player.intel_p_lvl[0] == 2:
                        value *= .25
                    if hit_player.intel_p_lvl[0] == 1:
                        value *= .50
                    self.send_chat("%s is wearing armor! Aim for the head!" % hit_player.name )
            if self.irpg_four == 5:
                if self.weapon_object.id < 2: #rifle smg
                    dice_roll = int( dice_roll / 3 ) 
                if dice_roll <= (150 / self.weapon_object.ammo) and hit_player.irpg_four != 0: #45% rifle, 30% smg, 25% shotgun -per pellet-
                    hit_player.irpg_reload_weapon(0)
                    hit_player.send_chat("You have been disarmed by %s !" % self.name)
                    self.send_chat("You disarmed %s!" % hit_player.name )
            if hit_player.irpg_four == 0:
                value *= 0.067
                self.send_chat("%s is a zombie, watch out!" % hit_player.name)
            if self.intel_p_lvl[5] > 0 and hit_player.irpg_four != 0:
                hit_player.send_chat("You have been poisoned by %s ! Get to the tent to cure it!" % self.name)
                self.send_chat("You poisoned %s !" % hit_player.name)
                hit_player.poisoner = self
                hit_player.poison = self.intel_p_lvl[5]
            if self.irpg_four == 3 and self.invisible:
                value *= .5 
            if self.irpg_five == 0 and self.hp > 0:
                modifier = 100.0 / self.hp
                value *= max(modifier, 2.0)
            if self.irpg_five == 3 and self.world_object.sneak and self.freaky_ammo > 0:
                self.freaky_ammo -= 1
                pos = (hit_player.world_object.position.x, hit_player.world_object.position.y, hit_player.world_object.position.z)
                hit_player.set_location_safe((self.world_object.position.x, self.world_object.position.y, self.world_object.position.z))
                self.set_location_safe(pos)
                hit_player.send_chat("You got body swapped by %s !" % self.name)
            return value

        def on_kill(self, killer, type, grenade):
            if killer == self and killer is not None:
                self.irpg_points -= 1 #Suicide penalty
            if killer != self and killer is not None:
                self.send_chat("Capture intel to get Intel Powers!")
                self.send_chat("Type /power for more info on Intel Powers")
                self.irpg_points -= 1 #Death penalty
                killer.irpg_points += 1 #Death reward
                if killer.irpg_four < 6:
                    self.send_chat("Type /four for info on level four powers.")
                if killer.irpg_five < 6:
                    self.send_chat("Type /five for info on level five powers.")
                if sum(self.intel_p_lvl) > sum(killer.intel_p_lvl):
                    self.irpg_points -= 1 #Power penalty
                    killer.irpg_points += 1 #Power reward
                self.send_chat("You were killed by %s who had %s" % (killer.name, killer.explain_power()))
                if killer.intel_p_lvl[2] > 0:
                    healamount = 0
                    if killer.intel_p_lvl[2] != 2 and type == HEADSHOT_KILL:
                        healamount += 10
                    if killer.intel_p_lvl[2] > 1:
                        healamount += 20
                    killer.heal_team(healamount, False)
                dice_roll = random.randint(1, 100)
                if killer.intel_p_lvl[6] > 0 and type == HEADSHOT_KILL:
                    if dice_roll <= 30 and killer.intel_p_lvl[6] == 3:
                        killer.nadesplode(self)
                    if dice_roll <= 15 and killer.intel_p_lvl[6] == 2:
                        killer.nadesplode(self)
                    if dice_roll <= 10 and killer.intel_p_lvl[6] == 1:
                        killer.nadesplode(self)
                if killer.streak == 9 and killer.team.other.flag.player != killer and killer.irpg_four > 6:
                    killer.intel_temporary()
                    killer.intel_temp = False
                    killer.send_chat("Your killstreak has given you a level!")
                    killer.send_chat("You have %s" % killer.explain_power())
                if self.four_points is None:
                    self.four_points = [0,0,0,0,0,0,0]
                if killer.irpg_four == 0:
                    killer.four_points[0] += 1
                    if killer.four_points[0] == 1:
                        killer.send_chat("Get five kills to unlock the Zombie Badge!")
                    if killer.four_points[0] == 5:
                        killer.send_chat("You unlocked the Zombie Badge!")
                    if killer.four_points[0] > 5:
                        killer.four_points[0] = 5
                if killer.irpg_four == 1:
                    killer.four_points[1] += 1
                    if killer.four_points[1] == 1:
                        killer.send_chat("Get five kills to unlock the Burst Badge!")
                    if killer.four_points[1] == 5:
                        killer.send_chat("You unlocked the Burst Badge!")
                    if killer.four_points[1] > 5:
                        killer.four_points[1] = 5
                if killer.irpg_four == 3 and killer.invisible:
                    killer.four_points[3] += 1
                    if killer.four_points[3] == 1:
                        killer.send_chat("Get five invisible kills to unlock the Ninja Badge!")
                    if killer.four_points[3] == 5:
                        killer.send_chat("You unlocked the Ninja Badge!")
                    if killer.four_points[3] > 5:
                        killer.four_points[3] = 5
                if killer.irpg_four == 4 and killer.world_object.velocity.z > 0.33:
                    killer.four_points[4] += 1
                    if killer.four_points[4] == 1:
                        killer.send_chat("Get five parachuting kills to unlock the Para Badge!")
                    if killer.four_points[4] == 5:
                        killer.send_chat("You unlocked the Para Badge!")
                    if killer.four_points[4] > 5:
                        killer.four_points[4] = 5
                if killer.irpg_four == 5 and self.weapon_object.current_ammo == 0:
                    killer.four_points[5] += 1
                    if killer.four_points[5] == 1:
                        killer.send_chat("Get five disarm kills to unlock the Disarm Badge!")
                    if killer.four_points[5] == 5:
                        killer.send_chat("You unlocked the Disarm Badge!")
                    if killer.four_points[5] > 5:
                        killer.four_points[5] = 5
                if killer.irpg_four == 6 and type == GRENADE_KILL:
                    killer.four_points[6] += 1
                    if killer.four_points[6] == 1:
                        killer.send_chat("Get five blocksplosion kills to unlock the Splode Badge!")
                    if killer.four_points[6] == 5:
                        killer.send_chat("You unlocked the Splode Badge!")
                    if killer.four_points[6] > 5:
                        killer.four_points[6] = 5
            if self is not None and killer is not None:
                if self.team.other.flag.player == self.team.other.flag.player:
                    self.irpg_points -= 1 #Intel penalty
                    if self != killer:
                        killer.irpg_points += 1 #Intel reward
                self.irpg_count()
                killer.irpg_count()
            if (self.irpg_four == 4 or self.irpg_five == 4) and self.parachute_count == 0:
                self.parachute_count = 1
                x, y, z = self.world_object.position.get()
                self.parachute_pos = (x, y, -100)
                self.send_chat("Prepare to parachute...")
            else:
                self.parachute_pos = None
                self.parachute_count = 0
            if sum(self.four_points) >= 560:
                self.send_chat("Type /five for more info on level 5 powers!")
            return connection.on_kill(self, killer, type, grenade)

        def on_fall(self, damage):
            if self.shocksplode_var == 0 and self.irpg_five == 4 and self.parachute_count == 1:
                self.shocksplode_var = 1
                self.shocksplode()
            if self.irpg_four == 4 or self.irpg_five == 4:
                return False
            return connection.on_fall(self, damage)

        def on_spawn(self, pos):
            if self.irpg_four == 1:
                self.rapid_hack_detect = False
                if self.weapon == 2:
                    self.send_chat("The shotgun cannot be used with burst fire.")
            else:
                self.rapid_hack_detect = True
            if self.irpg_four == 0:
                self.irpg_drop_weapon()
            if self.intel_p_lvl[1] > 0:
                self.irpg_reload_weapon( self.weapon_object.ammo + self.intel_p_lvl[1]*10 )
            if self.intel_p_lvl[3] == 3:
                self.teleport_uses = 4
            else:
                self.teleport_uses = 2
            self.freaky_ammo = 2
            self.poisoner = None
            self.poison = 0
            self.shocksplode_var = 0
            self.blocksplode_count = 5
            self.ohmygodjcabomb = None
            self.omgjab = None
            self.intel_downgrade()
            if sum(self.four_points) >= 560:
                self.send_chat("Type /five for more info on level 5 powers!")
            else:
                self.send_chat("Type /power for more information!")
            badges = self.explain_badges()
            if badges is not None:
                self.send_chat("%s" % badges)
            self.explain_four()
            self.send_chat("You have %s" % self.explain_power())
            return connection.on_spawn(self, pos)

        def on_spawn_location(self, pos):
            if self.parachute_pos is not None:
                return self.parachute_pos
            return connection.on_spawn_location(self, pos)

        def heal_team(self, value = 0, irpg_refill = False):
            healcount = 0
            for player in self.team.get_players():
                if player is not None and player.hp is not None and value is not None and player.hp > 0:
                    dist = distance_3d_vector(self.world_object.position, player.world_object.position)
                    if irpg_refill:
                        player.refill()
                        if player != self:
                            healcount = 0
                            player.send_chat("You have been resupplied by %s " % self.name)
                    elif dist <= 20.0 or player == self:
                        player.poison = 0
                        player.poisoner = None
                        player.set_hp(player.hp + value, type = FALL_KILL)
                        if player != self:
                            healcount += 1
                            player.send_chat("You have been healed by %s " % self.name)
            if healcount > 0:
                self.send_chat("Your kill has healed you and %s of your teammates!" % healcount)

        def intel_every_second(self):
            if self is None or self.hp <= 0:
                return
            self.headshot_splode = False
            if self.mobile_cooldown > 0:
                self.mobile_cooldown -= 1
            if self.mobile_cooldown == 0 and self.irpg_five == 2:
                mobile_count = 0
                for player in self.team.get_players():
                    dist = distance_3d_vector(self.world_object.position, player.world_object.position)
                    if dist <= 1 and mobile_count == 0 and player != self:
                        mobile_count = 1
                        player.refill()
                        player.send_chat("%s gave you a refill!" % self.name)
                        self.send_chat("You refilled %s" % player.name)
                        self.mobile_cooldown = 10
            if self.other_second is None:
                self.other_second = False
            if self.other_second:
                if self.irpg_five == 5:
                    if self.poison_block is not None:
                         x, y, z = self.poison_block[0], self.poison_block[1], self.poison_block[2]
                         map = self.protocol.map
                         covercount = 0
                         covercount += 1 if map.get_solid(x-1, y, z) else 0
                         covercount += 1 if map.get_solid(x+1, y, z) else 0
                         covercount += 1 if map.get_solid(x, y-1, z) else 0
                         covercount += 1 if map.get_solid(x, y+1, z) else 0
                         covercount += 1 if map.get_solid(x, y, z-1) else 0
                         covercount += 1 if map.get_solid(x, y, z+1) else 0
                         poisonbroke = False if map.get_solid(x, y, z) else True
                         if covercount >= 6 or poisonbroke:
                               self.poison_block = None
                               self.send_chat("Your poison block was deactivated!")
                         else:
                             for player in self.team.other.get_players():
                                 dist = distance_3d_vector(player.world_object.position, Vertex3(*self.poison_block))
                                 if dist <= 5 and player.poison < 2:
                                     player.send_chat("You have been poisoned by %s ! Get to the tent to cure it!" % self.name)
                                     self.send_chat("You poisoned %s !" % player.name)
                                     player.poisoner = self
                                     player.poison = 2
                if self.irpg_five == 1 and self.team.flag.player is not None and self.world_object.sneak:
                    x, y, z = self.team.flag.player.get_location()
                    self.send_chat('Intel carrier %s is in %s (%s, %s, %s)' % (self.team.flag.player.name, to_coordinates(x, y), int(x), int(y), int(z)))
                self.other_second = False
            else:
                self.other_second = True
            if self.ohmygodjcabomb is not None:
                if self.ohmygodjcabomb <= 0 and self.omgjab is not None:
                    self.omgjab.nadesplode(self)
                    self.ohmygodjcabomb = None
                    self.omgjab = None
                if self.ohmygodjcabomb > 0:
                    self.send_chat("%s ..." % self.ohmygodjcabomb )
                    self.ohmygodjcabomb -= 1
            if self.poison > 0 and self.poisoner is not None and self.poisoner.world_object is not None:
                self.hit(self.poison, self.poisoner)
            elif self.intel_p_lvl[4] > 0:
                if self.intel_p_lvl[4] == 3:
                    self.set_hp(self.hp + 5, type = FALL_KILL)
                if self.intel_p_lvl[4] == 2:
                    self.set_hp(self.hp + 3, type = FALL_KILL)
                if self.intel_p_lvl[4] == 1:
                    self.set_hp(self.hp + 2, type = FALL_KILL)
            if self.irpg_four == 2 and self.world_object.sneak:
                for player in self.team.get_players():
                    dist = distance_3d_vector(self.world_object.position, player.world_object.position)
                    if dist <= 16.0 and player.hp > 0:
                        if player.hp < 100:
                            if self.four_points is None:
                                self.four_points = [0,0,0,0,0,0,0]
                            player.set_hp(player.hp + 5, type = FALL_KILL)
                            self.four_points[2] += 5
                            if self.four_points[2] == 5:
                                self.send_chat("Heal 250 hp to unlock the Medic Badge!")
                            if self.four_points[2] == 250:
                                self.send_chat("You unlocked the Medic Badge!")
                            if self.four_points[2] > 250:
                                self.four_points[2] = 250
                        if player != self:
                            self.send_chat("Healing %s - %s hp" % (player.name, player.hp))

        def on_refill(self):
            if self.intel_p_lvl[1] > 0:
                self.irpg_reload_weapon( self.weapon_object.ammo + self.intel_p_lvl[1]*10 )
            if self.irpg_five == 3:
                self.send_chat("2 body swap uses refilled.")
                self.freaky_ammo = 2
            if self.intel_p_lvl[3] == 3:
                self.send_chat("4 gun-teleport uses refilled.")
                self.teleport_uses = 4
            elif self.intel_p_lvl[3] == 2:
                self.send_chat("2 gun-teleport uses refilled.")
                self.teleport_uses = 2
            elif self.irpg_four == 0:
                callLater(0.1,self.irpg_drop_weapon)
            if self.ohmygodjcabomb is not None:
                self.send_chat("The timebomb has been deactivated!")
                self.ohmygodjcabomb = None
                self.omgjab = None
            if self.poison > 0:
                self.send_chat("You have been cured of the poison!")
                self.poison = 0
                self.poisoner = None
            return connection.on_refill(self)
        
        def on_flag_take(self):
            if connection.on_flag_take(self) is not False and self.irpg_four > 6:
                self.intel_temporary()
                self.send_chat("Bring intel to your base to keep it!")
                self.send_chat("You have temporarily gained power: %s" % self.explain_temp())

        def on_flag_capture(self):
            if connection.on_flag_capture(self) is not False and self.irpg_four > 6:
                self.intel_temp = False
                self.send_chat("Type /power for more information!")
                self.send_chat("You have %s" % self.explain_power())
                self.irpg_points += 1 #Cap point reward
                self.irpg_count()
                if sum(self.intel_p_lvl) >= 10:
                    self.send_chat("Type /four for info on level four powers.")
            elif connection.on_flag_capture(self) is not False:
                if self.intel_power_pref < 7:
                    self.irpg_four = self.intel_power_pref
                    self.send_chat("You have %s" % self.explain_power())
                    self.explain_four()
                    self.irpg_points += 1 #Cap point reward
                    self.irpg_count()
            connection.on_flag_capture(self)
        def irpg_invis(self):
            self.invisible = True
            self.send_chat("You are invisible! 3 seconds of invisibility left!")
            kill_action = KillAction()
            kill_action.kill_type = FALL_KILL
            kill_action.player_id = kill_action.killer_id = self.player_id
            callLater(1.0 / NETWORK_FPS, self.protocol.send_contained,
                kill_action, sender = self)

        def irpg_uninvis(self):
            self.invisible = False
            x, y, z = self.world_object.position.get()
            create_player.player_id = self.player_id
            create_player.name = self.name
            create_player.x = x
            create_player.y = y
            create_player.z = z
            create_player.weapon = self.weapon
            create_player.team = self.team.id
            world_object = self.world_object
            input_data.player_id = self.player_id
            input_data.up = world_object.up
            input_data.down = world_object.down
            input_data.left = world_object.left
            input_data.right = world_object.right
            input_data.jump = world_object.jump
            input_data.crouch = world_object.crouch
            input_data.sneak = world_object.sneak
            input_data.sprint = world_object.sprint
            set_tool.player_id = self.player_id
            set_tool.value = self.tool
            set_color.player_id = self.player_id
            set_color.value = make_color(*self.color)
            weapon_input.primary = world_object.primary_fire
            weapon_input.secondary = world_object.secondary_fire
            self.protocol.send_contained(create_player, sender = self, save = True)
            self.protocol.send_contained(set_tool, sender = self)
            self.protocol.send_contained(set_color, sender = self, save = True)
            self.protocol.send_contained(input_data, sender = self)
            self.protocol.send_contained(weapon_input, sender = self)
            self.send_chat("You are now visible!")

        def on_block_build(self, x, y, z):
            if self.irpg_four == 6 and self.blocksplode_count > 0:
                if self.protocol.blocksplode_info is None:
                    self.protocol.blocksplode_info = {}
                self.protocol.blocksplode_info[(x, y, z)] = (self)
                self.blocksplode_count -= 1
                self.send_chat("Blocksplode block placed. %s remaining." % self.blocksplode_count )
            if self.irpg_five == 5:
                self.poison_block = (x, y, z)
                self.send_chat("Poison block placed. (Use right click to place normal blocks!)")
            connection.on_block_build(self, x, y, z)

        def on_block_build_attempt(self, x, y, z):
            if self.irpg_four == 6 and self.blocksplode_count > 0:
                color = (255, 0, 0)
                set_color.player_id = self.player_id
                set_color.value = make_color(*color)
                self.send_contained(set_color)
                self.protocol.send_contained(set_color, save = True)
            if self.irpg_five == 5:
                color = (128, 0, 255)
                set_color.player_id = self.player_id
                set_color.value = make_color(*color)
                self.send_contained(set_color)
                self.protocol.send_contained(set_color, save = True)
            connection.on_block_build_attempt(self, x, y, z)

        def on_block_removed(self, x, y, z):
            if self.protocol.blocksplode_info is None:
                self.protocol.blocksplode_info = {}
            blocksplode = self.protocol.blocksplode_info.pop((x, y, z), None)
            blocksplode_player = blocksplode
            if blocksplode_player is not None and blocksplode_player.irpg_four == 6:
                    blocksplode_player.blocksplode(x, y, z)
            connection.on_block_removed(self, x, y, z)

        def on_block_destroy(self, x, y, z, mode):
            for player in self.protocol.players.values():
                if player.irpg_five == 5:
                    if player.poison_block == (x, y, z):
                        if self.team != player.team:
                            self.send_chat("You have been cured of the poison!")
                            self.poison = 0
                            self.poisoner = None
            if self != self.team.other.flag.player:
                if self.teleport_uses == 0 and self.intel_p_lvl[3] >= 2 and self.tool == WEAPON_TOOL:
                    self.send_chat("You've run out of gun-teleport uses!")
                if self.intel_p_lvl[3] >= 2 and mode == DESTROY_BLOCK and self.tool == WEAPON_TOOL and self.teleport_uses > 0:
                    self.teleport_uses -= 1
                    self.send_chat("%s Gun-teleport uses remaining." % self.teleport_uses)
                    self.clear_tele_area(x, y, z)
                    self.set_location_safe((x, y, z-1))
                if self.intel_p_lvl[3] >= 1 and mode == GRENADE_DESTROY and self.headshot_splode == False:
                    self.set_location_safe((x, y, z-1))
                if self.irpg_four == 3 and mode == GRENADE_DESTROY and self.headshot_splode == False:
                    self.set_location_safe((x, y, z-1))
                    self.irpg_invis()
                    callLater(3, self.irpg_uninvis)
            else:
                if self.intel_p_lvl[3] >= 2 and mode == DESTROY_BLOCK and self.tool == WEAPON_TOOL:
                    self.send_chat("You can't teleport while holding intel!")
                if self.intel_p_lvl[3] >= 1 and mode == GRENADE_DESTROY:
                    self.send_chat("You can't teleport while holding intel!")
            return connection.on_block_destroy(self, x, y, z, mode)

        def clear_tele_area(self, x, y, z):
            map = self.protocol.map
            for nade_x in xrange(x - 1, x + 2):
                for nade_y in xrange(y - 1, y + 2):
                    for nade_z in xrange(z - 1, z + 2):
                        if nade_x > 0 and nade_x < 512 and nade_y > 0 and nade_y < 512 and nade_z > 0 and nade_z < 62:
                            map.remove_point(nade_x, nade_y, nade_z)
            block_action.x = x
            block_action.y = y
            block_action.z = z
            block_action.value = 3
            block_action.player_id = self.player_id
            self.protocol.send_contained(block_action, save = True)

        def intel_temporary(self):
            self.intel_temp = self.intel_upgrade()

        def intel_upgrade(self):
            if sum(self.intel_p_lvl) >= 21:
                return False
            dice_roll = random.randint(0, 6)
            if self.intel_power_pref != 7 and sum(self.intel_p_lvl) != 0:
                dice_roll = self.intel_power_pref
                if self.intel_p_lvl[dice_roll] < 3:
                    self.intel_p_lvl[dice_roll] += 1
                    return dice_roll
            while (self.intel_p_lvl[dice_roll] == 3):
                dice_roll = random.randint(0, 6)
            self.intel_power_pref = dice_roll if sum(self.intel_p_lvl) != 0 or self.intel_power_pref == 6 else self.intel_power_pref
            self.intel_p_lvl[dice_roll] += 1
            return dice_roll

        def intel_downgrade(self):
            if self.intel_temp is False:
                return
            self.intel_p_lvl[self.intel_temp] -= 1
            if self.intel_p_lvl[self.intel_temp] < 0:
                self.intel_p_lvl[self.intel_temp] = 0
            self.intel_temp = False

        def intel_punish(self):
            if sum(self.intel_p_lvl) >= 1 and INTEL_PUNISHMENT:
		#decrements power level according to this list:
                if self.intel_p_lvl[3] > 0 and self.intel_temp != 3:	#tele
                    self.intel_p_lvl[3] -= 1
                elif self.intel_p_lvl[4] > 0 and self.intel_temp != 4:	#regen
                    self.intel_p_lvl[4] -= 1
                elif self.intel_p_lvl[0] > 0 and self.intel_temp != 0:	#armor
                    self.intel_p_lvl[0] -= 1
                elif self.intel_p_lvl[5] > 0 and self.intel_temp != 5:	#poison
                    self.intel_p_lvl[5] -= 1
                elif self.intel_p_lvl[1] > 0 and self.intel_temp != 1:	#extmag
                    self.intel_p_lvl[1] -= 1
                elif self.intel_p_lvl[6] > 0 and self.intel_temp != 6:	#nadesplo
                    self.intel_p_lvl[6] -= 1
                elif self.intel_p_lvl[2] > 0 and self.intel_temp != 2:	#goodteam
                    self.intel_p_lvl[2] -= 1
                self.send_chat("Getting killstreaks will help prevent level loss!")
                self.send_chat("You lost a level! Be more careful!")

        def intel_clear(self):
            self.poison_block = None
            self.poisoner = None
            self.poison = 0
            self.mobile_cooldown = 0
            self.freaky_ammo = 2
            self.ohmygodjcabomb = None
            self.omgjab = None
            self.intel_p_lvl = [0,0,0,0,0,0,0]
            self.irpg_deadly = False
            self.other_second = False
            self.parachute_pos = None
            self.parachute_count = 1
            self.blocksplode_count = 5
            self.intel_power_pref = 7
            self.intel_temp = False
            self.irpg_four = 7
            self.irpg_five = 7

        def irpg_count(self):
            if INTEL_PUNISHMENT:
                if self.irpg_points >= 6:
                    self.irpg_points = 6
                    self.irpg_deadly = True
                else:
                    self.irpg_deadly = False
                if self.irpg_points <= 0:
                    self.intel_punish()
                    self.irpg_points = 4
            
        def on_shoot_set(self, fire):
            if self.irpg_four == 1 and self.tool == WEAPON_TOOL:
                if self.weapon == 2:
                    self.send_chat("The shotgun cannot be used with burst fire.") 
                    connection.on_shoot_set(self, fire)
                else:
                    set_tool.player_id = self.player_id
                    set_tool.value = self.tool
                    if self.weapon_object.shoot:
                        self.protocol.send_contained(set_tool)
                    else:
                        self.send_contained(set_tool)
            connection.on_shoot_set(self, fire)

    class IntelPowerProtocol(protocol):      
        blocksplode_info = None
        intel_second_counter = 0
        def on_game_end(self):
            for player in self.players.values():
                player.intel_clear()
            self.send_chat("Round is over! Intel Powers have been reset!")
            protocol.on_game_end(self)
        def on_map_change(self, map):
            self.blocksplode_info = None
            protocol.on_map_change(self, map)

        def on_world_update(self):
            self.intel_second_counter += 1
            if self.intel_second_counter >= 90:
                for player in self.players.values():
                    player.intel_every_second()
                self.intel_second_counter = 0
            protocol.on_world_update(self)

    return IntelPowerProtocol, IntelPowerConnection
